﻿using System;
using System.Collections.Generic;
using System.Text;
using ChemicalEquilibrium;

namespace NeuralModule
{
    /// <summary>
    /// 前突触
    /// 分类
    ///     简单前突触
    ///         功能:
    ///             将电位的变化转化为递质的释放
    ///         组成:
    ///             钾离子
    ///             钠离子
    ///             钙离子
    ///             电压门控钙离子通道
    ///             钙离子泵
    ///             递质
    ///             递质合成酶
    ///         平衡:
    ///             模块间离子平衡
    ///             膜内外离子平衡
    ///             递质的合成,摄入,释放三者平衡
    ///         过程:
    ///             在递质合成酶的作用下合成递质
    ///             转运体蛋白质将递质运送至囊泡内
    ///             膜电位的变化导致电压门控Ca通道开放
    ///             进入膜内的Ca离子使囊泡发生胞吐,囊泡释放递质
    ///             
    ///             
    /// </summary>
    public class Presynaptic
    {
        public List<ThreadEventWait> TEWs = new List<ThreadEventWait>();

        public Reactants FormerIonK, FormerIonNa, FormerIonCa, FormerIonCl;

        public Reactants IonK, IonNa, IonCa;

        public Reactants PumpCa;

        public Reactants ChannelCa;

        public Reactants Transmitter, TransmitterOut;

        public Reactants EnzymeCombine, EnzymeTransport;

        //囊泡
        public Reactants Vesicle;

        public IonicEquilibrium IECa;

        public IonicPump IPCa;

        public VoltageGated VGChannelCa;

        public ReactActivate RATransmitter;

        public ReactantTransform RTK, RTNa;

        public ReactIngest RITransmitter;

        public Presynaptic(Reactants FormerIonK, Reactants FormerIonNa, Reactants FormerIonCa, Reactants FormerIonCl)
        {
            this.FormerIonK = FormerIonK;
            this.FormerIonNa = FormerIonNa;
            this.FormerIonCa = FormerIonCa;
            this.FormerIonCl = FormerIonCl;

            Initialize();
        }

        public void Initialize()
        {
            //离子
            this.IonK = new Reactants(100000, 100000);
            this.IonNa = new Reactants(100000, 100000);
            this.IonCa = new Reactants(0, 1000);

            //离子通道
            this.ChannelCa = new Reactants(0, 100);

            //离子泵
            this.PumpCa = new Reactants(10, 0);

            //递质
            this.Transmitter = new Reactants(0, 1000);
            this.TransmitterOut = new Reactants(0, 1000);

            //递质合成酶
            this.EnzymeCombine = new Reactants(100, 0);

            //转运蛋白
            this.EnzymeTransport = new Reactants(100, 0);

            //囊泡
            this.Vesicle = new Reactants(0, 100);

            //离子平衡
            this.IECa = new IonicEquilibrium(this.ChannelCa.Active, this.IonCa.Active, this.IonCa.Inactive, 0.001f, 128, this.GetVoltage);

            //离子泵
            this.IPCa = new IonicPump(this.PumpCa.Active, new Queue<Reactant>[] { this.IonCa.Active }, new Queue<Reactant>[] { this.IonCa.Inactive }, new int[] { -1 }, new int[] { 0 });

            //电压门控
            this.VGChannelCa = new VoltageGated(this.ChannelCa, -50, 40, -60, 40, 20, this.GetVoltage);

            //递质合成
            this.RATransmitter = new ReactActivate(this.Transmitter.Active, this.TransmitterOut.Inactive, null, this.EnzymeCombine.Active, 2, 10, 1, 1);

            //递质摄取与释放
            this.RITransmitter = new ReactIngest(this.Vesicle.Active, this.Vesicle.Inactive, this.Transmitter.Active, this.TransmitterOut.Active, this.EnzymeTransport.Active, this.IonCa.Active, 10);

            //模块间离子平衡
            this.RTK = new ReactantTransform(this.FormerIonK, this.IonK);
            this.RTNa = new ReactantTransform(this.FormerIonNa, this.IonNa);

            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.IECa.Transport)));
            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.IPCa.Transport)));
            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.VGChannelCa.Transport)));
            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.RATransmitter.Activate)));
            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.RITransmitter.Ingest)));
            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.RITransmitter.Release)));
            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.RTK.Transform)));
            this.TEWs.Add(new ThreadEventWait(10, new OperateCallback(this.RTNa.Transform)));
        }


        public void Start()
        {
            foreach (ThreadEventWait TEW in this.TEWs) TEW.Start();
        }

        public void Abort()
        {
            foreach (ThreadEventWait TEW in this.TEWs) TEW.Abort();
        }

        float Capacitance = 0.0005f;
        public int GetVoltage()
        {
            int voltage = (int)((this.IonK.Active.Count + this.IonNa.Active.Count + this.IonCa.Active.Count * 2
                - this.IonK.Inactive.Count - this.IonK.Inactive.Count - this.IonCa.Inactive.Count * 2) * this.Capacitance);
            return voltage;
        }
    }
}
